﻿@using CacheManager.Core
@using System.Threading
@using Masuit.MyBlogs.Core.Common
@implements IAsyncDisposable
@inject ICacheManager<HashSet<string>> CacheManager
@inject IJSRuntime _js;

<span class="text-red online" @onclick="ShowViewer">@online</span>人正在浏览本文

@code {
    [Parameter]
    public int Id { get; set; }

    [Parameter]
    public string IP { get; set; }

    [Parameter]
    public bool IsAdmin { get; set; }

    int online;
    Timer _timer;

    protected override void OnInitialized()
    {
        try {
            var key = nameof(PostOnline) + ":" + Id;
            online = CacheManager.AddOrUpdate(key, new HashSet<string>(), set =>
            {
                set.Add(IP);
                return set;
            }, 3).Count;
            CacheManager.Expire(key, ExpirationMode.Sliding, TimeSpan.FromMinutes(5));
            _timer = new Timer(_ =>
            {
                try {
                    online = CacheManager.Get(key)?.Count ?? 0;
                    InvokeAsync(StateHasChanged);
                }
                catch{
                    // ignored
                }
            }, null, 0, 1000);
        }
        catch {
            // ignored
        }
    }

    public void ShowViewer()
    {
        if (online > 0 && IsAdmin)
        {
            try {
                _js.InvokeVoidAsync("showViewer", CacheManager.Get(nameof(PostOnline) + ":" + Id).Select(s => KeyValuePair.Create(s, s.GetIPLocation().ToString())));
            }
            catch {
                // ignored
            }
        }
    }

    public ValueTask DisposeAsync()
    {
        try {
            online = CacheManager.AddOrUpdate(nameof(PostOnline) + ":" + Id, new HashSet<string>(), set =>
            {
                set.Remove(IP);
                return set;
            }).Count;
        }
        catch {
            // ignored
        }
        return _timer?.DisposeAsync() ?? ValueTask.CompletedTask;
    }
}
